using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Crossborder.Common.Utility
{
    public static class OrderNumberGenerator
    {
        private static readonly ThreadLocal<int> _DailySequence = new ThreadLocal<int>(() => 0);
        private static readonly ThreadLocal<int> _DailySequence24 = new ThreadLocal<int>(() => 0);
        private static DateTime _LastDate = DateTime.MinValue;
        private static DateTime _LastDate24 = DateTime.MinValue;

        /// <summary>
        /// 生成 16 位订单号
        /// </summary>
        /// <returns></returns>
        public static string OrderGeneratorFor16()
        {
            lock (typeof(OrderNumberGenerator))
            {
                var now = DateTime.Now;

                // 日期变化是重置序列
                if (now.Date != _LastDate.Date)
                {
                    _DailySequence.Value = 0;
                    _LastDate = now;
                }
                var daily = _DailySequence.Value;

                // 生成10位时间戳
                string timePart = now.ToString("HHmmssfff");

                // 生成6位序列号
                int seq = Interlocked.Increment(ref daily) % 1000000;
                string seqPart = seq.ToString("D6");

                return timePart + seqPart;
            }
        }

        /// <summary>
        /// 生成 24位订单号（时间戳 + 随机数）
        /// </summary>
        /// <returns></returns>
        public static string OrderGeneratorFor24()
        {
            lock (typeof(OrderNumberGenerator))
            {
                var now = DateTime.Now;

                // 日期变化是重置序列
                if (now.Date != _LastDate24.Date)
                {
                    _DailySequence24.Value = 0;
                    _LastDate24 = now;
                }
                var daily = _DailySequence24.Value;

                // 生成18位时间戳
                string timePart = now.ToString("YYYYMMDDHHmmssfff");

                // 生成6位序列号
                int seq = Interlocked.Increment(ref daily) % 1000000;
                string seqPart = seq.ToString("D6");

                return timePart + seqPart;
            }
        }

        /// <summary>
        /// 生成 32位订单号（GUID哈希值）
        /// </summary>
        /// <returns></returns>
        public static string OrderGeneratorFor32()
        {
            using (var md5 = MD5.Create())
            {
                byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
                var str = new StringBuilder(32);
                foreach (var b in hash)
                {
                    str.Append(b.ToString("x2"));
                }
                return str.ToString();
            }
        }
    }
}